package org.sfx.rich

import java.lang.Class
import java.lang.annotation.Annotation
import java.lang.reflect.Method
import java.lang.reflect.Type
import org.sfx.rich.Enrich._

case class RichMethod(underlying: Method) {
  def returnType: Class[_] = underlying.getReturnType()
  def genericReturnType: Type = underlying.getGenericReturnType()
  def parameterTypes: Array[Class[_]] = underlying.getParameterTypes()
  def exceptionTypes: Array[Class[_]] = underlying.getExceptionTypes()
  def genericExceptionTypes: Array[Type] = underlying.getGenericExceptionTypes()
  def genericString: String = underlying.toGenericString()
  def invoke(obj: Object, args: Object*): Object = underlying.invoke(obj, args: _*)
  def isBridge: Boolean = underlying.isBridge()
  def isVarArgs: Boolean = underlying.isVarArgs()
  def defaultValue: Object = underlying.getDefaultValue()
  def parameterAnnotations: Array[Array[Annotation]] = underlying.getParameterAnnotations()
  def apply(obj: Object)(args: Object*): Object = underlying.invoke(obj, args: _*)

  def isGetter: Boolean = parameterTypes.size == 0 && underlying.name.startsWith("get") && underlying.name.length > 3
  def isSetter: Boolean = parameterTypes.size == 1 && underlying.name.startsWith("set") && underlying.name.length > 3
  def getterName: Option[String] = {
    if (isGetter) Some(underlying.name.charAt(3).toLower + underlying.name.substring(4)) else None
  }
  def setterName: Option[String] = {
    if (isSetter) Some(underlying.name.charAt(3).toLower + underlying.name.substring(4)) else None
  }
}
